<?php

namespace app\chat;

use app\chat\onmessage\AstroConsultLogin;
use app\chat\onmessage\ZyhsConsultLogin;
use app\common\cachemodel\live\LiveAwardAcitveRecord;
use app\common\cachemodel\live\LiveRecordingInfo;
use app\common\cachemodel\live\LiveStatusDataRecord;
use app\common\cachemodel\live\LiveZan;
use app\common\lib\exception\ApiException;
use app\common\lib\Util;
use app\zyhsapi\model\good_rtc_live\ZyhsGoodRtcLiveRecord;
use \GatewayWorker\Lib\Gateway;
use RuntimeException as RuntimeExceptionAlias;
use think\Env;
use think\Log;
use \Workerman\Lib\Timer;
use XznsTools\cache\CacheManage;

/**
 * This file is part of workerman.
 * Licensed under The MIT License
 * For full copyright and license information, please see the MIT-LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 * @author walkor<walkor@workerman.net>
 * @copyright walkor<walkor@workerman.net>
 * @link http://www.workerman.net/
 * @license http://www.opensource.org/licenses/mit-license.php MIT License
 */

/**
 * 用于检测业务代码死循环或者长时间阻塞等问题
 * 如果发现业务卡死，可以将下面declare打开（去掉//注释），并执行php start.php reload
 * 然后观察一段时间workerman.log看是否有process_timeout异常
 */
//declare(ticks=1);

/**
 * 聊天主逻辑
 * 主要是处理 onMessage onClose
 */
class MyEvent
{

    public const LOG_PRE = '直播聊天MyEvent：';
    public const DEBUG = true;

    /**
     * 参考：http://doc2.workerman.net/on-worker-start.html
     * 当businessWorker进程启动时触发。每个进程生命周期内都只会触发一次。
     * 可以在这里为每一个businessWorker进程做一些全局初始化工作，例如设置定时器，初始化redis等连接等。
     * 注意：$businessworker->onWorkerStart和Event::onWorkerStart不会互相覆盖，如果两个回调都设置则都会运行。
     * 不要在onWorkerStart内执行长时间阻塞或者耗时的操作，这样会导致BusinessWorker无法及时与Gateway建立连接，造成应用异常(SendBufferToWorker fail. The connections between Gateway and BusinessWorker are not ready错误)。
     * @param $businessWorker
     */
    public static function onWorkerStart($businessWorker): void
    {
        if (static::DEBUG)
        {
            echo "\n";
            echo "==========onWorkerStart start==========\n";
            echo "onWorkerStart function businessWorker:( " . json_encode($businessWorker, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . " )\n";
            echo "==========onWorkerStart end==========\n";
            echo "\n";
        }
        //初始化redis
        CacheManage::getInstance();
    }

    /**
     * 参考：http://doc2.workerman.net/on-web-socket-connect.html
     * 当客户端连接上gateway完成websocket握手时触发的回调函数。
     * 注意：此回调只有gateway为websocket协议并且gateway没有设置onWebSocketConnect时才有效。
     * 校验：1.HTTP_ORIGIN是否正确；2.是否携带token
     * @param $client_id
     * @param $data
     */
    public static function onWebSocketConnect($client_id, $data): void
    {
//        //判断连接来源是否合法，不合法就关掉连接
//        if (strpos($data['server']['HTTP_ORIGIN'], 'goddessxzns.com') !== true)
//        {//不包含字符串.goddessxzns.com
//            echo "==========HTTP_ORIGIN is error! 来源不合法========== " . $data['server']['HTTP_ORIGIN'] . "\n";
//            Gateway::closeClient($client_id);
//            $env = Env::get('host.name', 'local');
//            self::sendMsg('[' . $env . ']ws连接HTTP_ORIGIN不合法',
//                "# ws连接HTTP_ORIGIN不合法 \r\n\r\n " .
//                "环境：{$env} \r\n\r\n " .
//                "来源：{$data['server']['HTTP_ORIGIN']} \r\n\r\n ",
//                '');
//        } else
//        {//包含字符串.goddessxzns.com
//            echo "==========HTTP_ORIGIN is success! 来源合法========== " . $data['server']['HTTP_ORIGIN'] . "\n";
//        }
        if (static::DEBUG)
        {
            echo "\n";
            echo "==========onWebSocketConnect start==========\n";
            echo "onWebSocketConnect SERVER['HTTP_ORIGIN']:( " . json_encode($_SERVER, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . " )\n";
            echo "onWebSocketConnect function client_id:( $client_id )\n";
            echo "onWebSocketConnect function businessWorker:( " . json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . " )\n";
            echo "==========onWebSocketConnect end==========\n";
            echo "\n";
        }

    }

    /**
     * 参考：http://doc2.workerman.net/on-connect.html
     * 当客户端连接时触发
     * 如果业务不需此回调可以删除onConnect
     * 当客户端连接上gateway进程时(TCP三次握手完毕时)触发的回调函数。
     * @param string $client_id 连接id 例如：'7f00000108fd00000002'
     * @throws \Exception
     */
    public static function onConnect($client_id = ''): void
    {
        if (static::DEBUG)
        {
            echo "\n";
            echo "==========onConnect start==========\n";
            echo "onConnect function client_id:( $client_id )\n";
            echo "==========onConnect end==========\n";
            echo "\n";
        }

        // 连接到来后，定时30秒关闭这个链接，需要30秒内发认证并删除定时器阻止关闭连接的执行
        $_SESSION['auth_timer_id'] = Timer::add(30, function ($client_id)
        {
            if (static::DEBUG)
            {
                echo "\n";
                echo "==========onConnect Timer start==========\n";
                echo "Timer function client_id:( $client_id )，超过30秒，没有认证成功，关闭连接！\n";
                echo "==========onConnect Timer end==========\n";
                echo "\n";
            }
            Gateway::closeClient($client_id);
        }, [$client_id], false);

        //移步到 接口中（获取直播信息）
//        //发送公告信息
//        $config = (new AppConfig())->configInfo('live');
//        if (isset($config['live_notice'], $config['live_notice_color']))
//        {
//            Gateway::sendToCurrentClient(LiveMessage::msg('直播间公告消息', LiveMessage::MSG_TYPE_POP_MSG, [
//                'msg_info' => [
//                    'color' => $config['live_notice_color'],
//                    'content' => $config['live_notice'],
//                ]
//            ]));
//        } else
//        {
//            echo "error:直播公告消息未设置，请在后台-》App配置里进行配置，live_notice 和 live_notice_color\n";
//            Log::write('直播公告消息未设置，请在后台-》App配置里进行配置，live_notice 和 live_notice_color', 'error', true);
//        }
    }

    /**
     * 参考：http://doc2.workerman.net/on-messsge.html
     * 当客户端发来数据(Gateway进程收到数据)后触发的回调函数
     * @param string $client_id
     * @param mixed $message
     * @return void|bool
     * @throws ApiException
     */
    public static function onMessage(string $client_id = '', $message = [])
    {

        try
        {
            // debug
            if (static::DEBUG)
            {
                echo "\n";
                echo "==========onMessage start==========\n";
                echo "onMessage function client_id:( $client_id )\n";
                echo "session:(" . json_encode($_SESSION, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . ")\n";
                echo "server:(" . json_encode($_SERVER, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . ")\n";
                echo "message:(" . json_encode($message, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . ")\n";
                echo "==========onMessage end==========\n";
                echo "\n";
            }

            // 客户端传递的是json数据
            $message_data = json_decode($message, true);
            if (!$message_data)
            {
                Gateway::sendToCurrentClient(LiveMessage::show(0, 'json解析失败！'));
                Log::write('websocket onMessage：json解析失败【message_data=' . $message_data . '】', 'error', true);
                return;
            }

            // 判断是否有"action"
            if (!isset($message_data['action']))
            {
                Gateway::sendToCurrentClient(LiveMessage::show(0, '缺少action参数！'));
                Log::write('websocket onMessage：缺少action参数【message_data=' . $message_data . '】', 'error', true);
                return;
            }
            // 客户端发送的心跳数据，参考：http://doc2.workerman.net/heartbeat.html
            if ($message_data['action'] === 'ping')
            {
                return;
            }

            //判断live_id是否有效（先不做判断了）
//        $is_live_id_ok = false;
//        try
//        {
//            $live_info = (new LiveRecordingInfo())->getInfoById($message_data['live_id'], ['status']);
//            echo "live_info=========:(" . json_encode($live_info) . ")\n";
//            if ($live_info && 1 === (int)$live_info['status'])
//            {
//                $is_live_id_ok = true;
//            }
//        }
//        catch (\Exception $e)
//        {
//            $is_live_id_ok = false;
//        }
//        if (!$is_live_id_ok)
//        {
//            Gateway::sendToCurrentClient(LiveMessage::show(0, 'live_id无效！'));
//            throw new RuntimeExceptionAlias("\$message_data['live_id'] not set. client_ip:{$_SERVER['REMOTE_ADDR']} \$message:$message");
//        }

            // 根据类型执行不同的业务
            switch ($message_data['action'])
            {
                // 客户端登录 message格式: {type:login, name:xx, room_id:1} ，添加到客户端，广播给所有客户端xx进入聊天室
                case 'login'://登录
                    $loginType = (int)($message_data['login_type'] ?? 0);
                    if (in_array($loginType, [1, 2], true))
                    {
                        if ($loginType === 1 && (!isset($message_data['live_record_id']) || !$message_data['live_record_id']))
                        {
                            Gateway::sendToCurrentClient(LiveMessage::show(0, '进入优质连线直播间，缺少live_record_id参数！'));
                            Log::write('websocket onMessage：进入优质连线直播间，缺少live_record_id参数【message_data=' . $message_data . '】', 'error', true);
                            break;
                        }
                        if (isset($message_data['params']))
                        {
                            $message_data['params']['login_type'] = $loginType;
                            $auth = LiveMessage::zhunleAuth($message_data['params'], $client_id);
                            if (static::DEBUG)
                            {
                                echo "\n";
                                echo "==========onMessage action login start==========\n";
                                echo "onMessage function client_id:( $client_id )\n";
                                echo "auth:(" . json_encode($auth, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . ")\n";
                                echo "==========onMessage action login end==========\n";
                                echo "\n";
                            }
                            $uid = $auth['uid'];
                            if ($auth['code'] === 200)
                            {
                                Timer::del($_SESSION['auth_timer_id']);// 认证成功，删除 30关闭连接定时器
                                if ($uid)
                                {
                                    if (Gateway::isUidOnline($uid))
                                    {
                                        Gateway::unbindUid($client_id, $uid);
                                    }
                                    Gateway::bindUid($client_id, $uid);
                                    if (static::DEBUG)
                                    {
                                        echo "\n bindUid=success\n";
                                    }
                                }
                                $liveRecordId = $message_data['live_record_id'] ?? 0;
                                $_SESSION['app_type'] = $auth['app_type'];
                                $_SESSION['uid'] = $auth['uid'];
                                $_SESSION['uen'] = $auth['uen'];
                                $_SESSION['name'] = $auth['name'];
                                $_SESSION['avatar'] = $auth['avatar'];
                                $_SESSION['login_time'] = time();
                                $_SESSION['version'] = $auth['version'];
                                $_SESSION['live_record_id'] = $liveRecordId;
                                $_SESSION['user_type'] = $auth['user_type'];    // 5 准有好事 用户
                                $_SESSION['login_type'] = $loginType;    // 0=>直播间  1=>优质连线直播间 2=>连线咨询

                                switch ($loginType)
                                {
                                    case 1:
                                        Gateway::joinGroup($client_id, 'zyhs_good_rtc_live_room_' . $liveRecordId);
                                        if ($uid)
                                        {   // 发送 进入房间消息
                                            LiveMessage::sendMsg(LiveMessage::who(LiveMessage::WHO_TYPE_GOOD_RTC_LIVE_ROOM, 0, $liveRecordId), LiveMessage::MSG_TYPE_POP_GOOD_RTC_LIVE_USER_JOIN, [
                                                'user_info' => [
                                                    'name' => $auth['name'],
                                                ],
                                                'des' => '进入房间',
                                            ]);

                                            $jobData = [
                                                'app_type_num' => 2, // 1=>准有好事APP 2=>准了APP
                                                'type' => 'login',
                                                'uid' => $auth['uid'],
                                                'live_record_id' => $liveRecordId,
                                                'login_time' => $_SESSION['login_time'],
                                                'app_type' => $auth['app_type'],
                                            ];
                                            // 记录用户登录信息
                                            Util::queuePush('zyhs_good_rtc_live_login_or_out', $jobData);
                                            // 添加 更新在线人数 队列
                                            (new ZyhsGoodRtcLiveRecord())->addSyncOnlineNumQueue($auth['live_record_id']);
                                        }
                                        break;
                                }
                            } else
                            {   //发送给当前用户登录失败的消息
                                Gateway::sendToCurrentClient(LiveMessage::show($auth['code'], $auth['msg'], $message_data['action']));
                            }
                        } else
                        {
                            Gateway::sendToCurrentClient(LiveMessage::show(0, 'params 不能为空！', $message_data['action']));
                        }
                    } else
                    {   // 判断是否有直播id
                        if (!isset($message_data['live_id']))
                        {
                            Gateway::sendToCurrentClient(LiveMessage::show(0, '缺少live_id参数！'));
                            Log::write('websocket onMessage：缺少live_id参数【message_data=' . $message_data . '】', 'error', true);
                            throw new RuntimeExceptionAlias("\$message_data['live_id'] not set. client_ip:{$_SERVER['REMOTE_ADDR']} \$message:$message");
                        }
                        $live_id = $message_data['live_id'];
                        //token解析
                        if (isset($message_data['params']))
                        {
                            $auth = LiveMessage::auth($message_data['params'], $message_data['live_id'], $message_data['is_liver'] ?? 0, $client_id, $message_data['is_liver_admin'] ?? 0);
                            if (static::DEBUG)
                            {
                                echo "\n";
                                echo "==========onMessage action login start==========\n";
                                echo "onMessage function client_id:( $client_id )\n";
                                echo "auth:(" . json_encode($auth, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . ")\n";
                                echo "==========onMessage action login end==========\n";
                                echo "\n";
                            }
                            $uid = $auth['uid'];
                            if ($auth['code'] === 200 || $auth['code'] === 405)
                            {
                                Timer::del($_SESSION['auth_timer_id']);// 认证成功，删除 30关闭连接定时器

                                //$auth['user_type']【0：用户App端；1：是主播App端；2：是准了后台管理员；3：用户端管理员；】
                                if ($auth['user_type'] > 0)
                                {
                                    Gateway::joinGroup($client_id, $live_id . '_liver_or_admin');//主播端app 或者 准了后台的ws 或者 主播管理员，加入同一个组
                                } else
                                {
                                    Gateway::joinGroup($client_id, $live_id . '_app_user_group');//只有App用户端
                                }
//                            Gateway::joinGroup($client_id, $live_id);//加入群聊，房间号为直播id（所有用户）
                                if ($uid !== 0)
                                {
                                    if (Gateway::isUidOnline($uid))
                                    {
                                        Gateway::unbindUid($client_id, $uid);
                                    }
                                    Gateway::bindUid($client_id, $uid);
                                    if (static::DEBUG)
                                    {
                                        echo "\n bindUid=success\n";
                                    }
                                }
                                $_SESSION['app_type'] = $auth['app_type'];
                                $_SESSION['live_id'] = $live_id;
                                $_SESSION['uid'] = $auth['uid'];
                                $_SESSION['uen'] = $auth['uen'];
                                $_SESSION['name'] = $auth['name'];
                                $_SESSION['avatar'] = $auth['avatar'];
                                $_SESSION['vip_level'] = $auth['vip_level'];
                                $_SESSION['rank_index'] = $auth['rank_index'];
                                $_SESSION['user_type'] = $auth['user_type'];
                                $_SESSION['login_time'] = time();
                                $_SESSION['sign'] = $auth['sign'];
                                $_SESSION['version'] = $auth['version'];
                                $_SESSION['login_type'] = $loginType;    // 0=>直播间  1=>优质连线直播间 2=>连线咨询

                                //发送给当前用户登录成功的消息
                                Gateway::sendToCurrentClient(LiveMessage::msg($auth['msg'], LiveMessage::MSG_TYPE_LOGIN, [
                                    'user_info' => [
                                        'uen' => $auth['uen'],
                                        'name' => $auth['name'],
                                        'avatar' => $auth['avatar'],
                                        'vip_level' => $auth['vip_level'],
                                        'rank_index' => $auth['rank_index'],
                                        'sign' => $auth['sign'],
                                    ],
                                ], $auth['code']));
                                if ($uid !== 0)
                                {//当前用户已登录状态，发送给其他用户 *** 来了
                                    if ($auth['name'] !== '' && ($auth['app_type'] === 'android' || $auth['app_type'] === 'ios') && isset($message_data['relogin_time']) && $message_data['relogin_time'] === 1 && $auth['user_type'] === LiveMessage::USER_TYPE_APP_USER)
                                    {
                                        $return = LiveMessage::sendMsg(LiveMessage::who(LiveMessage::WHO_TYPE_ALL, $live_id, $live_id), LiveMessage::MSG_TYPE_POP_USER_COME, [
                                            'user_info' => [
                                                'uen' => $auth['uen'],
                                                'name' => $auth['name'],
                                                'avatar' => $auth['avatar'],
                                                'vip_level' => $auth['vip_level'],
                                                'rank_index' => $auth['rank_index'],
                                            ],
                                            'des' => '进入直播间',
                                        ]);
                                        if (static::DEBUG)
                                        {
                                            echo "\n";
                                            echo "==========LiveMessage::sendMsg pop_user_come start==========\n";
                                            echo "return:(" . json_encode($return, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . ")\n";
                                            echo "==========LiveMessage::sendMsg pop_user_come end==========\n";
                                            echo "\n";
                                        }
                                    }
                                    if ($auth['user_type'] === LiveMessage::USER_TYPE_APP_USER)
                                    {
                                        $jobData = [
                                            'type' => 'login',
                                            'uid' => $auth['uid'],
                                            'live_id' => $live_id,
                                            'login_time' => $_SESSION['login_time'],
                                            'app_type' => $auth['app_type'],
                                        ];
                                        // 记录用户登录信息
                                        Util::queuePush('live_login_or_out', $jobData);
                                    }
                                }
                            } else
                            {   //发送给当前用户登录失败的消息
                                Gateway::sendToCurrentClient(LiveMessage::show($auth['code'], $auth['msg'], $message_data['action']));
                            }
                        } else
                        {
                            Gateway::sendToCurrentClient(LiveMessage::show(0, 'params 不能为空！', $message_data['action']));
                        }
                    }
                    return;
                case 'zyhs_consult_login':   // 咨询用户登录
                    ZyhsConsultLogin::getInstance(static::DEBUG)->handle($client_id, $message_data);
                    break;
                case 'astro_consult_login':    // 咨询师登录
                    AstroConsultLogin::getInstance(static::DEBUG)->handle($client_id, $message_data);
                    break;
                case 'send_zan'://点赞
                    // 判断是否有直播id
                    if (!isset($message_data['live_id']))
                    {
                        Gateway::sendToCurrentClient(LiveMessage::show(0, '缺少live_id参数！'));
                        Log::write('websocket onMessage：缺少live_id参数【message_data=' . $message_data . '】', 'error', true);
                        throw new RuntimeExceptionAlias("\$message_data['live_id'] not set. client_ip:{$_SERVER['REMOTE_ADDR']} \$message:$message");
                    }
                    //验证$_SESSION['live_id'] 是否与 前端传过来的live_id是否一致
//                $live_id = $_SESSION['live_id'];
                    $live_id = $message_data['live_id'];

                    if (isset($message_data['params']['sign']))
                    {

                        $sign = (int)$message_data['params']['sign'];
                        $uid = Gateway::getUidByClientId($client_id);
                        if (empty($uid))
                        {
                            //用户未登录，的状态也可以发送点赞，不过点赞sign=0（用户在H5里 或者 “全推进入**直播”）
                            $sign = 0;
                            (new LiveStatusDataRecord())->setMinuteInc($live_id, 'zan_num', 1);//热度增加，未登录点赞不入库
                        } else
                        {
                            //点赞入库
                            // 获取最新的直播记录ID
                            $liveRecordId = (new LiveRecordingInfo())->getNewestRecord($live_id);
                            $data = [
                                'uid' => (int)$uid,
                                'live_id' => (int)$live_id,
                                'sign' => $sign,
                                'create_time' => time(),
                            ];
                            if (static::DEBUG)
                            {
                                echo "点赞 +1 :(" . json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . ")\n";
                            }
                            (new LiveZan())->insertZan($liveRecordId, $data);

                            try
                            {
                                // 参加抽奖活动
                                (new LiveAwardAcitveRecord())->awardActiveAdd((int)$live_id, $liveRecordId, (int)$uid, 2, '');
                            }
                            catch (\Exception $e)
                            {
                                Log::write("点赞参加活动判断异常：{$e->getMessage()};File:{$e->getFile()};Line:{$e->getLine()}", 'error', true);
                            }

                        }
                        //发送给直播间里的人点赞数据（点赞要排除当前的用户，因为 前端 1.是自己发送的时候，要不透明 2.不是自己发送的点赞，要透明）
                        LiveMessage::sendMsg(LiveMessage::who(LiveMessage::WHO_TYPE_ALL, $live_id, $live_id), LiveMessage::MSG_TYPE_POP_ZAN_SIGN, $sign, [$client_id]);

                    } else
                    {
                        Gateway::sendToCurrentClient(LiveMessage::show(0, 'sign 不能为空！', $message_data['action']));
                    }
                    return;
                default:
            }
        }
        catch (\Exception $e)
        {
            Log::write('websocket onMessage 处理异常：【message=' . $e->getMessage() . 'code=' . $e->getCode() . 'file=' . $e->getFile() . 'line=' . $e->getLine() . '】' . '【session=' . json_encode($_SESSION, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . ',server=' . json_encode($_SERVER, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . ',message=' . json_encode($message, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . '】', 'error', true);
        }
    }

    /**
     * 参考：http://doc2.workerman.net/on-close.html
     * 客户端与Gateway进程的连接断开时触发。不管是客户端主动断开还是服务端主动断开，都会触发这个回调。一般在这里做一些数据清理工作。
     * @param string $client_id 客户端id
     */
    public static function onClose($client_id = ''): void
    {
        try
        {
            // debug
            if (static::DEBUG)
            {
                echo "\n";
                echo " ==========onClose start ==========\n";
                echo "onClose function client_id:($client_id)\n";
                echo "session:(" . json_encode($_SESSION, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . ")\n";
                echo "server:(" . json_encode($_SERVER, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . ")\n";
                echo " ==========onClose end ==========\n";
                echo "\n";
            }

            if ($_SESSION && isset($_SESSION['user_type']))//用户类型：(0：不是主播；1：是主播App端；2：是准了后台管理员；)
            {
                switch ($_SESSION['user_type'])
                {//用户类型：(0：不是主播；1：是主播App端；2：是准了后台管理员；)
                    case 0:
                        switch ($_SESSION['login_type'])
                        {
                            case 0: // // 0=>直播间  1=>优质连线直播间 2=>连线咨询
                                $t = time();
                                $jobData = [
                                    'type' => 'login_out',
                                    'uid' => $_SESSION['uid'],
                                    'app_type' => $_SESSION['app_type'],
                                    'live_id' => $_SESSION['live_id'],
                                    'login_time' => $_SESSION['login_time'],
                                    'duration' => $t - $_SESSION['login_time'],  // 观看直播时长 秒
                                    'login_out_time' => $t,
                                ];
                                // 记录用户登录信息
                                Util::queuePush('live_login_or_out', $jobData);
                                break;
                            case 1:
                                $t = time();
                                $jobData = [
                                    'app_type_num' => 2,    // 1=>准有好事 || 2=>准了
                                    'type' => 'login_out',
                                    'uid' => $_SESSION['uid'],
                                    'live_record_id' => $_SESSION['live_record_id'],
                                    'login_time' => $_SESSION['login_time'],
                                    'duration' => $t - $_SESSION['login_time'],  // 观看直播时长 秒
                                    'login_out_time' => $t,
                                ];
                                // 记录用户登录信息
                                Util::queuePush('zyhs_good_rtc_live_login_or_out', $jobData);
                                // 添加 更新在线人数 队列
                                (new ZyhsGoodRtcLiveRecord())->addSyncOnlineNumQueue($_SESSION['live_record_id']);
                                break;
                            default:
                        }
                        break;
                    case 1:
                        //todo 主播端下线业务处理
                        Util::queuePush('live_close', ['live_id' => $_SESSION['live_id']], 300);

                        $env = Env::get('host.name', 'local');
                        self::sendMsg('[' . $env . ']直播主播链接断开',
                            "# 主播链接断开-如关闭直播请忽略 \r\n\r\n " .
                            "环境：{$env} \r\n\r\n " .
                            "直播间：{$_SESSION['live_id']} \r\n\r\n " .
                            "断开时间：" . date('Y-m-d H:i:s'),
                            '');
                        break;
                    case 2:
                        break;
                    case 5: // 准有好事用户
                        switch ($_SESSION['live_type'])
                        {
                            case 1: // 优质直播间 离开直播间更新信息
                                $t = time();
                                $jobData = [
                                    'app_type_num' => 1,
                                    'type' => 'login_out',
                                    'uid' => $_SESSION['uid'],
                                    'live_record_id' => $_SESSION['live_record_id'],
                                    'login_time' => $_SESSION['login_time'],
                                    'duration' => $t - $_SESSION['login_time'],  // 观看直播时长 秒
                                    'login_out_time' => $t,
                                ];
                                // 记录用户登录信息
                                Util::queuePush('zyhs_good_rtc_live_login_or_out', $jobData);
                                // 添加 更新在线人数 队列
                                (new ZyhsGoodRtcLiveRecord())->addSyncOnlineNumQueue($_SESSION['live_record_id']);
                                break;
                            default:
                        }
                        break;
                }
            }
        }
        catch (\Exception $e)
        {
            Log::write('websocket onClose 处理异常：【message=' . $e->getMessage() . 'code=' . $e->getCode() . 'file=' . $e->getFile() . 'line=' . $e->getLine() . '】' . '【session=' . json_encode($_SESSION, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . ',server=' . json_encode($_SERVER, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . '】', 'error', true);
        }

    }

    /**
     * 发送钉钉消息
     * @param $title
     * @param $contentMsg
     * @param $herfUrl
     */
    private static function sendMsg($title, $contentMsg, $herfUrl)
    {
        $time = time() * 1000;
        // PHP钉钉群
        $sec = 'SECcd9cc7f9e863073d9ebd0a2d0c9ed2f38d38ffcd67b700866d97ab3f919eb419';
        $sign = urldecode(base64_encode(hash_hmac('sha256', $time . "\n" . $sec, $sec, true)));
        $url = 'https://oapi.dingtalk.com/robot/send?access_token=b93977081e77642ab22db0e369abc12e08389a99441b3cc2ed6b3f675d8e9d7e';// 钉钉推送地址

        $url .= "&timestamp={$time}&sign={$sign}";

        Util::sendDingMsg($url, $title, $contentMsg, 3, $herfUrl);
    }

    /**
     * 参考：http://doc2.workerman.net/on-worker-stop.html
     * 当businessWorker进程退出时触发。每个进程生命周期内都只会触发一次。
     * 可以在这里为每一个businessWorker进程做一些清理工作，例如保存一些重要数据等。
     * @param $businessWorker
     */
    public static function onWorkerStop($businessWorker): void
    {
        if (static::DEBUG)
        {
            echo "\n";
            echo "==========onWorkerStop start==========\n";
            echo "onWorkerStop function businessWorker:( " . json_encode($businessWorker, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . " )\n";
            echo "==========onWorkerStop end==========\n";
            echo "\n";
        }
    }

}
